package com.lv.service.ui

import VideoHandle.EpDraw
import VideoHandle.EpEditor
import VideoHandle.EpEditor.OutputOption
import VideoHandle.EpVideo
import VideoHandle.OnEditorListener
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.SurfaceTexture
import android.graphics.drawable.BitmapDrawable
import android.media.MediaPlayer
import android.os.Environment
import android.text.Editable
import android.text.TextWatcher
import android.util.TypedValue
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.constraintlayout.widget.ConstraintLayout
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ScreenUtils
import com.blankj.utilcode.util.SizeUtils
import com.github.lany92.keyboard.KeyboardWatcher
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lv.common.base.BaseActivity
import com.lv.common.ktx.ToBitmap
import com.lv.common.utils.*
import com.lv.common.widget.TouchView
import com.lv.service.R
import com.lv.service.databinding.ActivityEditorVideoBinding
import com.lv.service.event.MediaSelectedEvent
import com.lv.service.event.MediaSelectedEventEnum
import com.lv.service.model.ServiceViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import org.koin.androidx.viewmodel.ext.android.viewModel


/**
 * 作者： ygx
 * 创建日期：2023/3/28 5:51 PM
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 * -    _              _           _     _   ____  _             _ _
 * -   / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * -  / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * - / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * -/_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 * <p>
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * 描述：视频编辑 - 添加文字 表情
 */
@Route(path = ARoutUtils.EditorVideoActivity)
class EditorVideoActivity : BaseActivity<ActivityEditorVideoBinding>(),
    View.OnClickListener {
    @Autowired(name = "mMediaUrl")
    @JvmField
    var mMediaUrl: String = ""

    @Autowired(name = "duration")
    @JvmField
    var mDuration: Int = 0

    @Autowired(name = "with")
    @JvmField
    var mWith: Int = 0

    @Autowired(name = "height")
    @JvmField
    var mHeight: Int = 0

    private var mMediaPlayer: MediaPlayer? = null
    private var manager: InputMethodManager? = null
    private var mCutPath = ""
    private var windowWidth: Int = 0
    private var windowHeight = 0
    private var mEditorType = 0// 0 编辑表情图片 1 编辑文字  3 视频剪辑
    private val drawableBg = intArrayOf(
        com.lv.common.R.drawable.bg_round_white,
        com.lv.common.R.drawable.bg_theme_round,
        com.lv.common.R.drawable.bg_fecd52_round,
        com.lv.common.R.drawable.bg_round_blue,
        com.lv.common.R.drawable.bg_round_green
    )
    private val colors =
        intArrayOf(
            com.lv.common.R.color.colorWhite,
            com.lv.common.R.color.color_EB613D,
            com.lv.common.R.color.color_EFCD52,
            com.lv.common.R.color.color_1864FE,
            com.lv.common.R.color.color_009C00
        )

    private val viewModelService: ServiceViewModel by viewModel()
    private val myScope: CoroutineScope = CoroutineScope(SupervisorJob())

    override fun getLayoutRes() = R.layout.activity_editor_video
    override fun initView() {
        super.initView()
        initStatusBar(this, true, false)
        ARouter.getInstance().inject(this)
        mBinding.apply {
            StatusBarUtil.setHeightAndPadding(this@EditorVideoActivity, viewSubToolbar)
            ivBackWhite.setOnClickListener(this@EditorVideoActivity)
            ivFace.setOnClickListener(this@EditorVideoActivity)
            ivInput.setOnClickListener(this@EditorVideoActivity)
            ivEditor.setOnClickListener(this@EditorVideoActivity)
            tvFinish.setOnClickListener(this@EditorVideoActivity)
            tvSubmit.setOnClickListener(this@EditorVideoActivity)
        }
    }


    override fun initConfig() {
        super.initConfig()
        mCutPath = mMediaUrl
        manager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager

        windowWidth = DensityUtil.getWindowWidth(this)
        windowHeight = DensityUtil.getWindowHeight(this)
        initColors()
    }

    override fun initData() {
        super.initData()

    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.iv_back_white -> {
//                LiveEventBus.get(FindGoodsPicEvent::class.java)
//                    .post(FindGoodsPicEvent("", "1"))
                finish()
            }
            R.id.iv_input -> {
                mEditorType = 1
                changeTextState(mBinding.rlEditText.visibility != View.VISIBLE)
            }
            R.id.iv_face -> {
                mEditorType = 0
                showEmotion()
            }
            R.id.iv_editor -> {
                mEditorType = 3
                ARouter.getInstance().build(ARoutUtils.EditorVideoCutActivity)
                    .withString("mMediaUrl", mCutPath).navigation(this, 0)
            }
            R.id.tv_finish -> {
                if (mEditorType == 0) {
                    mBinding.llEditorFinsh.visibility = View.GONE
                    if (mBinding.tvTag.text.isNotEmpty()) {
                        addTextToWindow()
                    }
                } else if (mEditorType == 1) {
                    changeTextState(mBinding.rlEditText.visibility != View.VISIBLE)
                    if (mBinding.etTag.text.isNotEmpty()) {
                        addTextToWindow()
                    }
                }
            }
            R.id.tv_submit -> {
                finishVideo()
            }

        }
    }


    private fun addTextToWindow() {
        val touchView = TouchView(this)
        val layoutParams: RelativeLayout.LayoutParams =
            RelativeLayout.LayoutParams(mBinding.tvTag.width, mBinding.tvTag.height)
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT)
        layoutParams.topMargin = mBinding.tvTag.top
        layoutParams.marginStart = mBinding.tvTag.left
        touchView.layoutParams = layoutParams
        val bitmap = mBinding.tvTag.ToBitmap()
        mBinding.tvTag.draw(Canvas(bitmap))
        touchView.background = BitmapDrawable(bitmap)

        touchView.setLimitsX(0, windowWidth)
        touchView.setLimitsY(
            0,
            windowHeight - StatusBarUtil.getStatusBarHeight(this) - SizeUtils.dp2px((50.0f + 110.0f))
        )
        touchView.setOnLimitsListener(object : TouchView.OnLimitsListener {
            override fun OnOutLimits(x: Float, y: Float) {
                mBinding.tvHintDelete.setTextColor(Color.RED)
            }

            override fun OnInnerLimits(x: Float, y: Float) {
                mBinding.tvHintDelete.setTextColor(Color.WHITE)
            }
        })
        touchView.setOnTouchListener(object : TouchView.OnTouchListener {
            override fun onDown(view: TouchView?, event: MotionEvent?) {
                mBinding.tvHintDelete.visibility = View.VISIBLE
                changeMode(false)
            }

            override fun onMove(view: TouchView?, event: MotionEvent?) {
            }

            override fun onUp(view: TouchView?, event: MotionEvent?) {
                mBinding.tvHintDelete.visibility = View.GONE
                changeMode(true)
                if (view?.isOutLimits == true) {
                    mBinding.rlTouchView.removeView(view)
                }
            }
        })
        mBinding.rlTouchView.addView(touchView)

        mBinding.etTag.setText("")
        mBinding.tvTag.text = ""
    }

    //更改界面模式
    private fun changeMode(flag: Boolean) {
        if (flag) {
            mBinding.ivBackWhite.visibility = View.VISIBLE
            mBinding.llBottom.visibility = View.VISIBLE
        } else {
            mBinding.ivBackWhite.visibility = View.GONE
            mBinding.llBottom.visibility = View.GONE
        }
    }

    /**
     * 更改文字输入状态的界面
     */
    private fun changeTextState(flag: Boolean) {
        if (flag) {
            mBinding.rlEditText.visibility = View.VISIBLE
            mBinding.tvTag.visibility = View.INVISIBLE
            mBinding.llEditorFinsh.visibility = View.VISIBLE
            mBinding.ivBackWhite.visibility = View.GONE
            mBinding.tvVideo.setDrawMode(flag)
            mBinding.tvVideo.setNewPaintColor(resources.getColor(colors[currentColorPosition]))
            mBinding.llColor.visibility = View.VISIBLE

            popupEditText()
        } else {
            manager?.hideSoftInputFromWindow(
                mBinding.etTag.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
            mBinding.tvTag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30f)
            mBinding.rlEditText.visibility = View.GONE
            mBinding.ivBackWhite.visibility = View.VISIBLE
            mBinding.tvVideo.setDrawMode(flag)
            mBinding.tvTag.visibility = View.VISIBLE
            mBinding.llColor.visibility = View.GONE
            mBinding.llEditorFinsh.visibility = View.GONE
        }
    }

    private var isFirstShowEditText = false

    /**
     * 弹出键盘
     */
    private fun popupEditText() {
        isFirstShowEditText = true
        mBinding.etTag.viewTreeObserver
            .addOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener {
                if (isFirstShowEditText) {
                    isFirstShowEditText = false
                    mBinding.etTag.isFocusable = true
                    mBinding.etTag.isFocusableInTouchMode = true
                    mBinding.etTag.requestFocus()
                    isFirstShowEditText = !(manager?.showSoftInput(mBinding.etTag, 0) ?: false)
                }
            })
    }

    override fun initEvents() {
        super.initEvents()
        mBinding.etTag.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }

            override fun afterTextChanged(s: Editable?) {
                mBinding.tvTag.text = s.toString()
            }
        })
        mBinding.textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
            override fun onSurfaceTextureAvailable(
                surface: SurfaceTexture,
                width: Int,
                height: Int
            ) {
                initMediaPlay(surface)
            }

            override fun onSurfaceTextureSizeChanged(
                surface: SurfaceTexture,
                width: Int,
                height: Int
            ) {
            }

            override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
                return false
            }

            override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}
        }

        setOnKeyBordListener()
    }

    private fun setOnKeyBordListener() {
        val layoutParams =
            mBinding.viewKeybordSub.layoutParams as ConstraintLayout.LayoutParams
        KeyboardWatcher(
            this
        ) { showKeyboard, height ->
            layoutParams.height = if (showKeyboard) (height - SizeUtils.dp2px(50.0f)) else 1
            mBinding.viewKeybordSub.layoutParams = layoutParams
        }

    }


    private fun initMediaPlay(surface: SurfaceTexture) {
        try {
            mMediaPlayer = MediaPlayer()
            mMediaPlayer?.setDataSource(mMediaUrl)
            mMediaPlayer?.setSurface(Surface(surface))
            mMediaPlayer?.setScreenOnWhilePlaying(true)
            mMediaPlayer?.isLooping = true
            mMediaPlayer?.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT)
            mMediaPlayer?.setOnPreparedListener(MediaPlayer.OnPreparedListener {
                // 设置视频缩放模式为适应屏幕
                mMediaPlayer?.start()
                updateTextureViewAspectRatio()
            })
            mMediaPlayer?.prepareAsync()
//            mDuration = mMediaPlayer?.duration ?: 0
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun updateTextureViewAspectRatio() {
        val videoWidth = mMediaPlayer?.videoWidth ?: 0
        val videoHeight = mMediaPlayer?.videoHeight ?: 0
        if (videoWidth > 0 && videoHeight > 0) {
            val videoAspectRatio = videoWidth.toFloat() / videoHeight.toFloat()
            val textureViewWidth = mBinding.textureView.width
//            val textureViewWidth = parentWidth
            val textureViewHeight = (textureViewWidth / videoAspectRatio).toInt()

            val layoutParams = mBinding.textureView.layoutParams as RelativeLayout.LayoutParams
            layoutParams.height = textureViewHeight
            mBinding.textureView.layoutParams = layoutParams
        }
    }

    private fun finishVideo() {
        if ((mDuration) > Constants.VIDEO_DURATION_CIR) {
            return showToast("您要发布的视频时间过长")
        }
        LiveEventBus.get(MediaSelectedEvent::class.java)
            .post(MediaSelectedEvent(MediaSelectedEventEnum.VIDEO, mCutPath, mWith, mHeight))
        finish()
//        startLoading()
//        lifecycleScope.launchWhenCreated {
//            withContext(myScope.coroutineContext) {
//                val imageProcess = withContext(Dispatchers.IO) {
//                    doImageProcess(mMediaUrl)
//                }
//                doEpVideo(imageProcess)
//            }
//        }

    }

    private fun doEpVideo(epVideo: EpVideo): String {
        val outPath =
            getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.absolutePath + "/CameraCir/" + "${System.currentTimeMillis()}.mp4"
        EpEditor.exec(epVideo, OutputOption(outPath), object : OnEditorListener {
            override fun onSuccess() {
                runOnUiThread {
                    loadFinished()
                }
                LiveEventBus.get(MediaSelectedEvent::class.java)
                    .post(MediaSelectedEvent(MediaSelectedEventEnum.VIDEO, mCutPath))
                finish()
            }

            override fun onFailure() {
                runOnUiThread {
                    loadFinished()
                    showToast("编辑失败")
                }
            }

            override fun onProgress(v: Float) {
                LogUtils.e("编辑进度==${v * 100}")
            }
        })
        mCutPath = outPath
        return outPath
    }

    private fun doImageProcess(path: String): EpVideo {
        mMediaPlayer?.stop()
        //得到涂鸦view的bitmap图片
        val videoWidth = mMediaPlayer?.videoWidth ?: ScreenUtils.getScreenWidth()
        val videoHeight = mMediaPlayer?.videoHeight ?: ScreenUtils.getScreenWidth()
        //得到涂鸦view的bitmap图片
        val bitmap =
            Bitmap.createBitmap(
                videoWidth,
                videoHeight,
                Bitmap.Config.ARGB_8888
            )
        mBinding.rlTuya.draw(Canvas(bitmap))
//        val bitmap = mBinding.rlTouchView.ToBitmap()
//        val bitmap = SaveImageUtils.convertViewToBitmap(mBinding.rlTouchView)
//        //这步是根据视频尺寸来调整图片宽高,和视频保持一致
//        val matrix = Matrix()
//        matrix.postScale(
//            videoWidth * 1f / bitmap.width,
//            videoHeight * 1f / bitmap.height
//        )
//        val bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
        val saveBitmap = SaveImageUtils.saveBitmapPNG(this, bitmap, "temp")
        val epDraw = EpDraw(saveBitmap, 0, 0, bitmap.width * 1.0f, bitmap.height * 1.0f, false)
        val epVideo = EpVideo(path)
        epVideo.addDraw(epDraw)
        return epVideo
    }


    private var currentColorPosition = 0

    /**
     * 初始化底部颜色选择器
     */
    private fun initColors() {
        val dp20 = SizeUtils.dp2px(20.0f)
        val dp25 = SizeUtils.dp2px(25.0f)
        for (x in drawableBg.indices) {
            val relativeLayout = RelativeLayout(this)
            val layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT)
            layoutParams.weight = 1f
            relativeLayout.layoutParams = layoutParams
            val view = View(this)
            view.setBackgroundDrawable(resources.getDrawable(drawableBg.get(x)))
            val layoutParams1 = RelativeLayout.LayoutParams(dp20, dp20)
            layoutParams1.addRule(RelativeLayout.CENTER_IN_PARENT)
            view.layoutParams = layoutParams1
            relativeLayout.addView(view)
            val view2 = View(this)
            view2.setBackgroundResource(com.lv.common.R.drawable.color_click)
            val layoutParams2 = RelativeLayout.LayoutParams(dp25, dp25)
            layoutParams2.addRule(RelativeLayout.CENTER_IN_PARENT)
            view2.layoutParams = layoutParams2
            if (x != 0) {
                view2.visibility = View.GONE
            }
            relativeLayout.addView(view2)
            val position: Int = x
            relativeLayout.setOnClickListener { v ->
                if (currentColorPosition != position) {
                    view2.visibility = View.VISIBLE
                    val parent = v.parent as ViewGroup
                    val childView = parent.getChildAt(currentColorPosition) as ViewGroup
                    childView.getChildAt(1).visibility = View.GONE
                    mBinding.tvVideo.setNewPaintColor(resources.getColor(colors.get(position)))
                    mBinding.etTag.setTextColor(resources.getColor(colors.get(position)))
                    mBinding.tvTag.setTextColor(resources.getColor(colors.get(position)))
                    currentColorPosition = position
                }
            }
            mBinding.llColor.addView(relativeLayout, x)
        }
    }

    private fun showEmotion() {
//        val emotionDialogFragment =
//            EmotionDialogFragment.newInstance(true)
//        emotionDialogFragment.show(supportFragmentManager, emotionDialogFragment.tag)
//        emotionDialogFragment.setOnDisMissCallBack(object :
//            EmotionDialogFragment.OnDisMissCallBack {
//            override fun onDismiss() {
//                if (mBinding.tvTag.text.isNotEmpty()) {
//                    addTextToWindow()
//                }
//            }
//
//            override fun saveCommend(text: String) {
//                val handlerEmojiText = FaceManager.handlerEmojiText(text)
//                val text1 = mBinding.tvTag.text
//                mBinding.tvTag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 50f)
//                FaceManager.handlerEmojiText(mBinding.tvTag, "$text1$handlerEmojiText")
//                mBinding.tvTag.visibility = View.VISIBLE
//            }
//
//            override fun onCommendTextChanged(contend: String?) {
//                val text = mBinding.tvTag.text
//                if (text.isNullOrEmpty()) {
//                    mBinding.tvTag.visibility = View.INVISIBLE
//                    return
//                }
//                val lastIndexOf = text.lastIndexOf("[")
//                val drop = text.subSequence(0, lastIndexOf)
//                FaceManager.handlerEmojiText(mBinding.tvTag, drop)
//            }
//        })
    }

    private fun playNewUrl(newUrl: String?) {
        try {
            mMediaPlayer?.reset()
            mMediaPlayer?.setDataSource(newUrl)
            mMediaPlayer?.prepareAsync()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }

    override fun onResume() {
        super.onResume()
        mMediaPlayer?.start()
    }

    override fun onPause() {
        super.onPause()
        mMediaPlayer?.pause()
    }

    override fun onDestroy() {
        super.onDestroy()
        mMediaPlayer?.release()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data == null) {
            return
        }
        if (resultCode != RESULT_OK) {
            return
        }
        when (requestCode) {
            0 -> {
                val path = data.getStringExtra("PARAMS_CROP_RESULT_PATH")
                mDuration = data.getFloatExtra("duration", 0.0f).toInt()
                if (!path.isNullOrEmpty()) {
                    mCutPath = path
                    mMediaUrl = path
                    playNewUrl(mMediaUrl)
                }
            }
        }
    }
}